package com.aiprompt.demos.manager;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.aiprompt.demos.exception.ErrorCode;
import com.aiprompt.demos.exception.ThrowUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;

@Slf4j
@Service
public class BigModelManager {
    @Value("${api.key}")
    private String apiKey;

    @Value("${api.url}")
    private String apiUrl;

    public String generateResponse(String systemPrompt, String userMessage) {

        ThrowUtils.throwIf(apiKey == null || apiUrl == null, ErrorCode.PARAMS_ERROR, "apiKey or apiUrl is null");
        JSONObject requestBody = buildRequestBody(systemPrompt, userMessage);

        HttpResponse response = sendHttpRequest(requestBody);
        // 解析响应
        return parseResponse(response);
    }

    private JSONObject buildRequestBody(String systemPrompt, String userMessage) {
        JSONObject requestBody = new JSONObject();

        requestBody.put("model", "glm-4.5");
        requestBody.put("stream", false);

        JSONArray messages = new JSONArray();

        // 系统消息
        JSONObject systemMsg = new JSONObject();
        systemMsg.put("role", "system");
        systemMsg.put("content", systemPrompt);
        messages.add(systemMsg);

        // 用户消息
        JSONObject userMsg = new JSONObject();
        userMsg.put("role", "user");
        userMsg.put("content", userMessage);
        messages.add(userMsg);

        requestBody.put("messages", messages);
        return requestBody;
    }

    private HttpResponse sendHttpRequest(JSONObject requestBody) {
        return HttpRequest.post(apiUrl)
                .header("Content-Type", "application/json")
                .header("Authorization", "Bearer " + apiKey)
                .body(requestBody.toString())
                .timeout(30000)
                .execute();
    }

    private String parseResponse(HttpResponse response) {
        if (response.getStatus() != 200) {
            throw new RuntimeException("API请求失败: HTTP " + response.getStatus());
        }

        JSONObject jsonResponse = JSONUtil.parseObj(response.body());
        return jsonResponse.getJSONArray("choices")
                .getJSONObject(0)
                .getJSONObject("message")
                .getStr("content");
    }

    /**
     * 流式生成响应
     */
    public void generateStreamResponse(String systemPrompt, String userMessage, SseEmitter emitter) {
        log.info("开始流式生成响应，用户消息: {}", userMessage);
        ThrowUtils.throwIf(apiKey == null || apiUrl == null, ErrorCode.PARAMS_ERROR, "apiKey or apiUrl is null");

        try {
            // 发送开始事件
            emitter.send(SseEmitter.event()
                .name("start")
                .data("开始生成..."));

            JSONObject requestBody = buildStreamRequestBody(systemPrompt, userMessage);
            log.info("请求体构建完成: {}", requestBody.toString());

            sendStreamHttpRequest(requestBody, emitter);
        } catch (Exception e) {
            log.error("流式生成过程中发生错误", e);
            try {
                emitter.send(SseEmitter.event()
                    .name("error")
                    .data("生成失败: " + e.getMessage()));
                emitter.complete();
            } catch (IOException ioException) {
                log.error("发送错误事件失败", ioException);
                emitter.completeWithError(ioException);
            }
        }
    }

    private JSONObject buildStreamRequestBody(String systemPrompt, String userMessage) {
        JSONObject requestBody = new JSONObject();

        requestBody.put("model", "glm-4.5");
        requestBody.put("stream", true); // 启用流式输出

        JSONArray messages = new JSONArray();

        // 系统消息
        JSONObject systemMsg = new JSONObject();
        systemMsg.put("role", "system");
        systemMsg.put("content", systemPrompt);
        messages.add(systemMsg);

        // 用户消息
        JSONObject userMsg = new JSONObject();
        userMsg.put("role", "user");
        userMsg.put("content", userMessage);
        messages.add(userMsg);

        requestBody.put("messages", messages);
        return requestBody;
    }

    private void sendStreamHttpRequest(JSONObject requestBody, SseEmitter emitter) {
        try {
            log.info("开始发送HTTP请求到: {}", apiUrl);
            URL url = new URL(apiUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Authorization", "Bearer " + apiKey);
            connection.setDoOutput(true);
            connection.setConnectTimeout(10000); // 10秒连接超时
            connection.setReadTimeout(30000);    // 30秒读取超时

            // 发送请求体
            try (java.io.OutputStream outputStream = connection.getOutputStream()) {
                outputStream.write(requestBody.toString().getBytes(StandardCharsets.UTF_8));
            }

            // 检查响应状态
            int responseCode = connection.getResponseCode();
            log.info("HTTP响应状态码: {}", responseCode);

            if (responseCode != 200) {
                // 读取错误响应
                String errorResponse = "";
                try (BufferedReader errorReader = new BufferedReader(
                        new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8))) {
                    String line;
                    StringBuilder sb = new StringBuilder();
                    while ((line = errorReader.readLine()) != null) {
                        sb.append(line);
                    }
                    errorResponse = sb.toString();
                }
                log.error("API请求失败，状态码: {}, 错误响应: {}", responseCode, errorResponse);

                emitter.send(SseEmitter.event()
                    .name("error")
                    .data("API请求失败，状态码: " + responseCode + ", 错误: " + errorResponse));
                emitter.complete();
                return;
            }

            // 读取流式响应
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {

                log.info("开始读取流式响应");
                String line;
                int lineCount = 0;
                while ((line = reader.readLine()) != null) {
                    lineCount++;
                    log.debug("读取到第{}行: {}", lineCount, line);

                    if (line.startsWith("data: ")) {
                        String data = line.substring(6);
                        if ("[DONE]".equals(data)) {
                            log.info("接收到完成标记，结束流式读取");
                            break;
                        }

                        if (data.trim().isEmpty()) {
                            continue; // 跳过空数据行
                        }

                        try {
                            JSONObject jsonData = JSONUtil.parseObj(data);
                            JSONArray choices = jsonData.getJSONArray("choices");
                            if (choices != null && choices.size() > 0) {
                                JSONObject choice = choices.getJSONObject(0);
                                JSONObject delta = choice.getJSONObject("delta");
                                if (delta != null && delta.containsKey("content")) {
                                    String content = delta.getStr("content");
                                    if (content != null && !content.isEmpty()) {
                                        log.debug("发送内容片段: {}", content);
                                        emitter.send(SseEmitter.event()
                                            .name("message")
                                            .data(content));
                                    }
                                }
                            }
                        } catch (Exception e) {
                            log.warn("解析数据行失败: {}, 错误: {}", data, e.getMessage());
                            // 忽略解析错误，继续处理下一行
                        }
                    }
                }

                log.info("流式响应读取完成，共处理{}行", lineCount);
                emitter.send(SseEmitter.event()
                    .name("done")
                    .data(""));
                emitter.complete();

            }
        } catch (Exception e) {
            try {
                emitter.send(SseEmitter.event()
                    .name("error")
                    .data("请求失败: " + e.getMessage()));
                emitter.complete();
            } catch (IOException ioException) {
                emitter.completeWithError(ioException);
            }
        }
    }

}
